#include <stdio.h>
#include <string.h>

int main()
{
    //1.以只读模式打开名为"myfile"的文件，返回文件指针fp
    FILE* fp = fopen("myfile", "r");
    //2.检查文件是否成功打开：若fopen返回NULL，说明打开失败
    if (!fp)
    {
        printf("fopen error!\n");  
        return 1;  
    }

    //3.定义要比较的字符串内容，末尾带换行符
    const char* msg = "hello sanqiu\n";

    //4.无限循环，直到遇到文件结束标志才退出
    while (1)
    {
        //4.1：定义用于存储读取内容的缓冲区，大小为1024字节
        char buf[1024];

        //4.2：从文件中读取数据到缓冲区
        size_t s = fread(buf, 1, strlen(msg), fp);
        //注意：fread函数主要作用是按指定的大小和数量，从文件中读取数据块并存储到内存缓冲区中，适用于读取文本文件和二进制文件（如图片、音频等）

        /* fread的参数说明：
        *   第一个参数（void *ptr）：指向内存缓冲区的起始地址，用于存储从文件中读取的数据
        *     此处为buf，即读取到的内容将被存入该字符数组
        *
        *   第二个参数（size_t size）：每个数据块的大小（单位：字节）
        *     此处为1，表示每个数据块是1字节（按字节读取）
        *
        *   第三个参数（size_t nmemb）：计划读取的数据块数量
        *     此处为strlen(msg)，表示要读取与msg字符串长度相同的字节数（例如：msg长度为10，则读取10个1字节块）
        *
        *   第四个参数（FILE *stream）：指向源文件的指针，即要从中读取数据的文件
        *     此处为fp，即之前用fopen以只读模式打开的文件
        *
        *   返回值（size_t）：实际成功读取的数据块数量（不是字节数）
        *     若全部读取成功，返回值等于strlen(msg)（每个块1字节，即总字节数等于返回值）
        *     若读取发生错误，返回值会小于nmemb
        */

        //4.3：如果读取到的字节数大于0，说明有有效数据读取
        if (s > 0)
        {
            //第一步：在读取内容的末尾添加字符串结束符'\0'，使其成为合法字符串
            buf[s] = 0;

            //第二步：打印读取到的内容
            printf("%s", buf);
        }

        //4.4：检查是否到达文件末尾：feof返回非0表示已到文件末尾
        if (feof(fp))
        {
            break;  // 跳出循环，结束读取
        }
    }

    //6.关闭文件流，释放文件资源
    fclose(fp);

    //6.关闭后 fp 指针变为野指针,将其置空
    fp = NULL;

    printf("文件已经成功关闭\n");
    return 0;  
}
